package com.kexio.email.impl;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import com.kexio.common.dto.Result;
import com.kexio.email.builder.EmailBuilder;
import com.kexio.email.config.EmailProperties;
import com.kexio.email.entity.EmailAttachment;
import com.kexio.email.entity.EmailRecord;
import com.kexio.email.enums.EmailStatus;
import com.kexio.email.service.EmailService;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.mail.internet.MimeMessage;

/**
 * 邮件服务实现
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
@ConditionalOnProperty(prefix = "kexio.email", name = "enabled", havingValue = "true")
public class EmailServiceImpl implements EmailService {
    
    private static final Logger logger = LoggerFactory.getLogger(EmailServiceImpl.class);
    
    @Autowired
    private EmailProperties emailProperties;
    
    @Autowired(required = false)
    private JavaMailSender mailSender;
    
    // 模拟存储 (实际应该注入Mapper)
    private final Map<String, EmailRecord> recordStorage = new HashMap<>();
    
    @Override
    public Result<EmailRecord> sendTextEmail(String to, String subject, String content) {
        logger.info("发送文本邮件: to={}, subject={}", to, subject);
        
        try {
            EmailRecord record = EmailBuilder.textEmail(to, subject, content)
                .from(emailProperties.getSender().getDefaultFromEmail(), 
                      emailProperties.getSender().getDefaultFromName())
                .build();
            
            boolean sendResult = doSendEmail(record, null);
            updateRecordStatus(record, sendResult, null);
            
            recordStorage.put(record.getId(), record);
            
            return Result.success(sendResult ? "发送成功" : "发送失败", record);
            
        } catch (Exception e) {
            logger.error("发送文本邮件异常", e);
            return Result.error("发送文本邮件异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<EmailRecord> sendHtmlEmail(String to, String subject, String htmlContent) {
        logger.info("发送HTML邮件: to={}, subject={}", to, subject);
        
        try {
            EmailRecord record = EmailBuilder.htmlEmail(to, subject, htmlContent)
                .from(emailProperties.getSender().getDefaultFromEmail(), 
                      emailProperties.getSender().getDefaultFromName())
                .build();
            
            boolean sendResult = doSendEmail(record, null);
            updateRecordStatus(record, sendResult, null);
            
            recordStorage.put(record.getId(), record);
            
            return Result.success(sendResult ? "发送成功" : "发送失败", record);
            
        } catch (Exception e) {
            logger.error("发送HTML邮件异常", e);
            return Result.error("发送HTML邮件异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<EmailRecord> sendEmailWithAttachments(String to, String subject, String content, 
                                                       List<EmailAttachment> attachments) {
        logger.info("发送带附件邮件: to={}, subject={}, attachments={}", to, subject, attachments.size());
        
        try {
            EmailBuilder builder = EmailBuilder.htmlEmail(to, subject, content)
                .from(emailProperties.getSender().getDefaultFromEmail(), 
                      emailProperties.getSender().getDefaultFromName());
            
            // 添加附件
            if (attachments != null) {
                for (EmailAttachment attachment : attachments) {
                    builder.attach(attachment);
                }
            }
            
            EmailRecord record = builder.build();
            
            boolean sendResult = doSendEmail(record, attachments);
            updateRecordStatus(record, sendResult, null);
            
            recordStorage.put(record.getId(), record);
            
            return Result.success(sendResult ? "发送成功" : "发送失败", record);
            
        } catch (Exception e) {
            logger.error("发送带附件邮件异常", e);
            return Result.error("发送带附件邮件异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<EmailRecord> sendTemplateEmail(String to, String templateCode, Map<String, Object> templateParams) {
        logger.info("发送模板邮件: to={}, templateCode={}", to, templateCode);
        
        try {
            EmailRecord record = EmailBuilder.templateEmail(to, templateCode, templateParams)
                .from(emailProperties.getSender().getDefaultFromEmail(), 
                      emailProperties.getSender().getDefaultFromName())
                .build();
            
            // 这里应该渲染模板，简化处理
            record.setSubject("模板邮件: " + templateCode);
            record.setContent("模板内容: " + templateParams);
            
            boolean sendResult = doSendEmail(record, null);
            updateRecordStatus(record, sendResult, null);
            
            recordStorage.put(record.getId(), record);
            
            return Result.success(sendResult ? "发送成功" : "发送失败", record);
            
        } catch (Exception e) {
            logger.error("发送模板邮件异常", e);
            return Result.error("发送模板邮件异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<EmailRecord> sendTemplateEmail(String to, String templateCode, Map<String, Object> templateParams,
                                               List<EmailAttachment> attachments) {
        return sendTemplateEmail(to, templateCode, templateParams);
    }
    
    @Override
    public Result<String> batchSendEmail(List<String> toList, String subject, String content, boolean isHtml) {
        logger.info("批量发送邮件: recipients={}, subject={}, isHtml={}", toList.size(), subject, isHtml);
        
        try {
            int successCount = 0;
            int failedCount = 0;
            
            for (String to : toList) {
                Result<EmailRecord> result = isHtml ? 
                    sendHtmlEmail(to, subject, content) : 
                    sendTextEmail(to, subject, content);
                
                if (result.isSuccess()) {
                    successCount++;
                } else {
                    failedCount++;
                }
            }
            
            String message = String.format("批量发送完成: 成功%d条, 失败%d条", successCount, failedCount);
            return Result.success(message, "BATCH_" + System.currentTimeMillis());
            
        } catch (Exception e) {
            logger.error("批量发送邮件异常", e);
            return Result.error("批量发送邮件异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<String> batchSendTemplateEmail(List<String> toList, String templateCode, Map<String, Object> templateParams) {
        logger.info("批量发送模板邮件: recipients={}, templateCode={}", toList.size(), templateCode);
        
        try {
            int successCount = 0;
            int failedCount = 0;
            
            for (String to : toList) {
                Result<EmailRecord> result = sendTemplateEmail(to, templateCode, templateParams);
                if (result.isSuccess()) {
                    successCount++;
                } else {
                    failedCount++;
                }
            }
            
            String message = String.format("批量发送完成: 成功%d条, 失败%d条", successCount, failedCount);
            return Result.success(message, "BATCH_" + System.currentTimeMillis());
            
        } catch (Exception e) {
            logger.error("批量发送模板邮件异常", e);
            return Result.error("批量发送模板邮件异常: " + e.getMessage());
        }
    }
    
    @Override
    public Result<String> sendEmailAsync(String to, String subject, String content, boolean isHtml) {
        // 异步发送的简化实现，实际应该放入队列
        String recordId = IdUtil.fastSimpleUUID();
        
        // 异步执行 (这里简化为同步)
        Result<EmailRecord> result = isHtml ? 
            sendHtmlEmail(to, subject, content) : 
            sendTextEmail(to, subject, content);
        
        return result.isSuccess() ? 
            Result.success("邮件已加入发送队列", recordId) :
            Result.error("邮件加入队列失败");
    }
    
    @Override
    public Result<String> sendTemplateEmailAsync(String to, String templateCode, Map<String, Object> templateParams) {
        String recordId = IdUtil.fastSimpleUUID();
        
        // 异步执行 (这里简化为同步)
        Result<EmailRecord> result = sendTemplateEmail(to, templateCode, templateParams);
        
        return result.isSuccess() ? 
            Result.success("模板邮件已加入发送队列", recordId) :
            Result.error("模板邮件加入队列失败");
    }
    
    @Override
    public EmailRecord getRecord(String recordId) {
        return recordStorage.get(recordId);
    }
    
    @Override
    public String getStatus(String recordId) {
        EmailRecord record = recordStorage.get(recordId);
        return record != null ? record.getStatus() : null;
    }
    
    @Override
    public Result<Boolean> retryEmail(String recordId) {
        EmailRecord record = recordStorage.get(recordId);
        if (record == null) {
            return Result.error("邮件记录不存在");
        }
        
        if (record.getRetryCount() >= record.getMaxRetryCount()) {
            return Result.error("已达到最大重试次数");
        }
        
        // 重试发送
        record.setRetryCount(record.getRetryCount() + 1);
        boolean result = doSendEmail(record, null);
        updateRecordStatus(record, result, null);
        
        return Result.success(result ? "重试成功" : "重试失败", result);
    }
    
    @Override
    public Result<Boolean> cancelEmail(String recordId) {
        EmailRecord record = recordStorage.get(recordId);
        if (record == null) {
            return Result.error("邮件记录不存在");
        }
        
        record.setStatus(EmailStatus.CANCELLED.getCode());
        return Result.success("邮件已取消", true);
    }
    
    @Override
    public Map<String, Object> getStatistics(String timeRange) {
        Map<String, Object> stats = new HashMap<>();
        
        // 模拟统计数据
        stats.put("totalSent", recordStorage.size());
        stats.put("successCount", recordStorage.values().stream()
            .mapToLong(r -> EmailStatus.SUCCESS.getCode().equals(r.getStatus()) ? 1 : 0)
            .sum());
        stats.put("failedCount", recordStorage.values().stream()
            .mapToLong(r -> EmailStatus.FAILED.getCode().equals(r.getStatus()) ? 1 : 0)
            .sum());
        stats.put("timeRange", timeRange);
        
        return stats;
    }
    
    @Override
    public int processPendingEmails() {
        // 处理待发送邮件队列的逻辑
        logger.info("处理待发送邮件队列");
        return 0;
    }
    
    @Override
    public int cleanExpiredRecords() {
        // 清理过期记录的逻辑
        logger.info("清理过期邮件记录");
        return 0;
    }
    
    /**
     * 实际发送邮件逻辑
     */
    private boolean doSendEmail(EmailRecord record, List<EmailAttachment> attachments) {
        try {
            if (mailSender == null) {
                logger.warn("JavaMailSender未配置，邮件发送失败");
                return false;
            }
            
            // 判断是否是HTML邮件或有附件
            boolean isHtml = "html".equalsIgnoreCase(record.getEmailType());
            boolean hasAttachments = attachments != null && !attachments.isEmpty();
            
            // HTML邮件或有附件时使用MimeMessage
            if (isHtml || hasAttachments) {
                return sendMimeEmail(record, attachments);
            } else {
                // 纯文本邮件使用SimpleMailMessage
                return sendSimpleEmail(record);
            }
            
        } catch (Exception e) {
            logger.error("邮件发送失败", e);
            record.setErrorMessage(e.getMessage());
            return false;
        }
    }
    
    /**
     * 发送简单邮件
     */
    private boolean sendSimpleEmail(EmailRecord record) {
        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(getFromAddress(record));
            message.setTo(record.getToEmails().split(";"));
            message.setSubject(record.getSubject());
            message.setText(record.getContent());
            
            mailSender.send(message);
            return true;
            
        } catch (Exception e) {
            logger.error("发送简单邮件失败", e);
            return false;
        }
    }
    
    /**
     * 发送复杂邮件 (HTML + 附件)
     */
    private boolean sendMimeEmail(EmailRecord record, List<EmailAttachment> attachments) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            // 如果有附件，第二个参数为true；否则为false以提高性能
            boolean multipart = attachments != null && !attachments.isEmpty();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, multipart, "UTF-8");
            
            helper.setFrom(getFromAddress(record), getFromName(record));
            helper.setTo(record.getToEmails().split(";"));
            helper.setSubject(record.getSubject());
            
            // 判断内容类型
            boolean isHtml = "html".equalsIgnoreCase(record.getEmailType());
            helper.setText(record.getContent(), isHtml); // 第二个参数：true表示HTML，false表示纯文本
            
            // 添加附件
            if (multipart && attachments != null) {
                for (EmailAttachment attachment : attachments) {
                    if (attachment.isValid() && attachment.getContent() != null) {
                        helper.addAttachment(attachment.getName(), 
                            () -> new java.io.ByteArrayInputStream(attachment.getContent()));
                    }
                }
            }
            
            mailSender.send(mimeMessage);
            logger.debug("邮件发送成功: to={}, subject={}, isHtml={}, attachments={}", 
                record.getToEmails(), record.getSubject(), isHtml, multipart);
            return true;
            
        } catch (Exception e) {
            logger.error("发送复杂邮件失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 获取发件人地址
     */
    private String getFromAddress(EmailRecord record) {
        if (StrUtil.isNotBlank(record.getFromEmail())) {
            return record.getFromEmail();
        }
        return emailProperties.getSender().getDefaultFromEmail();
    }
    
    /**
     * 获取发件人名称
     */
    private String getFromName(EmailRecord record) {
        if (StrUtil.isNotBlank(record.getFromName())) {
            return record.getFromName();
        }
        return emailProperties.getSender().getDefaultFromName();
    }
    
    /**
     * 更新记录状态
     */
    private void updateRecordStatus(EmailRecord record, boolean success, Exception error) {
        if (success) {
            record.setStatus(EmailStatus.SUCCESS.getCode());
            record.setCompleteTime(LocalDateTime.now());
        } else {
            record.setStatus(EmailStatus.FAILED.getCode());
            if (error != null) {
                record.setErrorMessage(error.getMessage());
            }
        }
        record.setDuration(100L); // 模拟发送耗时
    }
}
